package com.whl.basic.service.impl;

import com.whl.basic.constant.VerifyCodeConstants;
import com.whl.basic.dto.SmsCodeDto;
import com.whl.basic.exception.BusinessException;
import com.whl.basic.service.IVerifyCodeService;
import com.whl.basic.util.SmsUtil;
import com.whl.basic.util.StrUtils;
import com.whl.basic.util.VerifyCodeUtils;
import com.whl.user.domain.User;
import com.whl.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.concurrent.TimeUnit;

/**
 * 验证码业务类
 */
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    /**
     * 图形验证码业务类
     * @param key
     * @return
     */
    @Override
    public String imageCode(String key) {
        // 判断key是否为空
        if(key == null){
            throw new BusinessException("key为空");
        }
        // 调用工具类，获取随机验证码
        String code = StrUtils.getComplexRandomString(4);
        // 将验证码放到redis中保存，并设置有效期
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        // 调用工具类，把验证码的值合并到图片中，使用base64编码，并返回base64编码的字符串
        return VerifyCodeUtils.verifyCode(110,40,code);
    }

    /**
     * 用户注册发送手机验证码
     * @param smsCodeDto
     */
    @Override
    public void sendSmsCode(SmsCodeDto smsCodeDto) {
        // 获取电话
        String phone = smsCodeDto.getPhone();
        // 获取输入的图形验证码
        String inputImageCode = smsCodeDto.getImageCode();
        // 获取redis中保存imageCode的key
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        // 校验 - 空值校验
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("请输入电话号码!!!");
        }
        if(StringUtils.isEmpty(inputImageCode)){
            throw new BusinessException("请输入图形验证码!!!");
        }
        if(StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("请重新刷新页面，获取图形验证码!!!");
        }

        // 校验 - 图形验证码校验 - 图形验证码是否过期
        Object imageCodeValue = redisTemplate.opsForValue().get(imageCodeKey);
        if(imageCodeValue == null){ // 第一次获取或已经过期了
            throw new BusinessException("请重新获取图形验证码!!!");
        }
        // 图片验证码是否正确
        if(!imageCodeValue.toString().equalsIgnoreCase(inputImageCode)){
            throw new BusinessException("请输入正确图形验证码!!!");
        }
        // 校验 - 手机号是否被注册过
        User user = userMapper.findByPhone(phone);
        if(user != null){
            throw new BusinessException("该手机号已经注册过了，请直接登录!!!");
        }

        // 获取手机验证码 - 判断是否过期  register:1111111
        Object redisSmsCode = redisTemplate.opsForValue().get(VerifyCodeConstants.REGISTERCODE_PREFIX + phone);
        String code = null;
        if(redisSmsCode == null){ // 第一次发送 or 手机验证码过期了
            // 过期了就用新的验证码
            code = StrUtils.getComplexRandomString(6);
        }else { // 没有过期
            // 验证是否已经过了重发时间
            // 以前保存的时间
            Long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            // 现在的时间
            long nowTime = System.currentTimeMillis();
            // 没有过期 -  判断是否过了重发时间
            if((nowTime - redisTime) < 1*60*1000){ // 没有过重发时间
                throw new BusinessException("请勿重复获取验证码!!!");
            }else {
                // 没有过期就用以前的
                code = redisSmsCode.toString().split(":")[0];
            }
        }
        // 保存到redis  -  [register:phone, code:System.currentTimeMillis()] - currentTimeMillis时间戳
        // 刷新了过期时间
        redisTemplate.opsForValue().set(VerifyCodeConstants.REGISTERCODE_PREFIX + phone,code + ":" + System.currentTimeMillis(),3,TimeUnit.MINUTES);

        // 发送短信
        // SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请勿在3分钟内使用!!!");
        System.out.println("你的验证码为：" + code + ",请在3分钟内使用!!!");
    }

    /**
     * 微信登录手机绑定验证码
     * @param smsCodeDto
     */
    @Override
    public void sendBinderSmsCode(SmsCodeDto smsCodeDto) {
        // 获取电话
        String phone = smsCodeDto.getPhone();
        // 校验 - 空值校验
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("请输入电话号码!!!");
        }
        // 获取手机验证码 - 判断是否过期  register:1111111
        Object redisSmsCode = redisTemplate.opsForValue().get(VerifyCodeConstants.BINDER_CODE_PREFIX + phone);
        String code = null;
        if(redisSmsCode == null){ // 第一次发送 or 手机验证码过期了
            // 过期了就用新的验证码
            code = StrUtils.getComplexRandomString(6);
        }else { // 没有过期
            // 验证是否已经过了重发时间
            // 以前保存的时间 [register:phone, code:System.currentTimeMillis()] - currentTimeMillis时间戳
            long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            // 现在的时间
            long nowTime = System.currentTimeMillis();
            // 没有过期 -  判断是否过了重发时间
            if((nowTime - redisTime) < 1*60*1000){ // 没有过重发时间
                throw new BusinessException("请勿重复获取验证码!!!");
            }else {
                // 没有过期就用以前的
                code = redisSmsCode.toString().split(":")[0];
            }
        }
        // 保存到redis  -  [register:phone, code:System.currentTimeMillis()] - currentTimeMillis时间戳
        // 刷新了过期时间
        redisTemplate.opsForValue().set(VerifyCodeConstants.BINDER_CODE_PREFIX + phone,code + ":" + System.currentTimeMillis(),3,TimeUnit.MINUTES);
        // 发送短信
        // SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请勿在3分钟内使用!!!");
        System.out.println("你的验证码为：" + code + ",请在3分钟内使用!!!");
    }
}
